// 测试handletelemetryData方法的独立脚本

// 日志函数，替代原来的this._log
function _log(level, message) {
    const timestamp = new Date().toLocaleTimeString('zh-CN');
    console.log(`[${timestamp}] [${level}] ${message}`);
}

/** 
 * 解析工程数据格式 - 根据用户提供的参考代码实现
 * @param {string} hexString - 十六进制字符串（可带空格或不带） 
 * @returns {object} - 解析后的结果对象 
 */ 
function parseEngineeringData(hexString) {
    try {
        // 去掉空格 
        hexString = hexString.replace(/\s+/g, '');

        // 验证输入是否为有效的十六进制字符串
        if (!/^[0-9A-Fa-f]+$/.test(hexString)) {
            _log('ERROR', '[遥测数据解析] 无效的十六进制字符串');
            return null;
        }

        // 十六进制转字节数组 
        const bytes = new Uint8Array(hexString.length / 2); 
        for (let i = 0; i < bytes.length; i++) {
            bytes[i] = parseInt(hexString.substr(i * 2, 2), 16); 
        }

        const view = new DataView(bytes.buffer); 
        let offset = 0; 

        // 按工程数据格式读取 - 根据用户提供的方案严格实现
        const result = {
            // 工程数据格式头部字段
            packLen: view.getUint32(offset, true), // 包长：4字节，无符号长整数，小端序
            packNo: view.getUint32(offset += 4, true), // 报序号：4字节，无符号长整数，小端序
            taskID: view.getUint32(offset += 4, true), // 任务ID：4字节，无符号长整数，小端序
            modlID: view.getUint32(offset += 4, true), // 型号ID：4字节，无符号长整数，小端序
            no: view.getUint16(offset += 4, true), // 编号：2字节，无符号短整数，小端序
            danType: view.getUint8(offset += 2), // 源类型：1字节，单字节
            dataType: view.getUint8(offset += 1), // 数据类型：1字节，单字节
            parNum: view.getUint32(offset += 1, true), // 参数个数：4字节，无符号长整数，小端序
            state: view.getUint8(offset += 4), // 数据状态：1字节，单字节
            workMode: view.getUint8(offset += 1), // 工作模式：1字节，单字节
            reserved1: view.getUint8(offset += 1), // 备用1：1字节，单字节
            sample: view.getUint16(offset += 1, true), // 采样率：2字节，无符号短整数，小端序
            reserved2: view.getUint8(offset += 2), // 备用2：1字节，单字节
            reserved3: view.getUint8(offset += 1), // 备用3：1字节，单字节

            // 系统时间字段
            sysTime: {
                hour: view.getUint32(offset += 1, true), // 系统时间-时：4字节，无符号长整数，小端序
                minute: view.getUint32(offset += 4, true), // 系统时间-分：4字节，无符号长整数，小端序
                second: view.getUint32(offset += 4, true), // 系统时间-秒：4字节，无符号长整数，小端序
                ms: view.getUint32(offset += 4, true), // 系统时间-毫秒：4字节，无符号长整数，小端序
            },

            // 数据时间字段
            dataTime: {
                hour: view.getUint32(offset += 4, true), // 数据时间-时：4字节，无符号长整数，小端序
                minute: view.getUint32(offset += 4, true), // 数据时间-分：4字节，无符号长整数，小端序
                second: view.getUint32(offset += 4, true), // 数据时间-秒：4字节，无符号长整数，小端序
                ms: view.getUint32(offset += 4, true), // 数据时间-毫秒：4字节，无符号长整数，小端序
            },

            params: []
        };

        // 验证值域并添加日志
        if (result.packLen < 80 || result.packLen > 32080) {
            _log('WARN', `[遥测数据解析] 包长值超出范围: ${result.packLen}`);
        }
        _log('DEBUG', `[遥测数据解析] 包长(packLen): ${result.packLen}`);
        
        if (result.packNo < 1) {
            _log('WARN', `[遥测数据解析] 报序号值超出范围: ${result.packNo}`);
        }
        _log('DEBUG', `[遥测数据解析] 报序号(packNo): ${result.packNo}`);
        
        _log('DEBUG', `[遥测数据解析] 任务ID(taskID): ${result.taskID}`);
        _log('DEBUG', `[遥测数据解析] 型号ID(modlID): ${result.modlID}`);
        _log('DEBUG', `[遥测数据解析] 编号(no): ${result.no}`);
        
        // 源类型名称映射 - 根据用户方案修正
        const sourceTypeNames = {
            0: '同型号编号',
            1: '外测',
            2: '干扰',
            3: '靶机'
        };
        result.sourceTypeName = sourceTypeNames[result.danType] || `未知(${result.danType})`;
        _log('DEBUG', `[遥测数据解析] 源类型(danType): ${result.danType} (${result.sourceTypeName})`);
        
        // 数据类型名称映射 - 根据用户方案修正
        let dataTypeName = '未知数据类型';
        switch (result.dataType) {
            case 0:
                dataTypeName = 'PCM';
                break;
            case 1:
                dataTypeName = '工程参数';
                break;
            case 2:
                dataTypeName = '视频图像数据';
                break;
            case 3:
                dataTypeName = '音频数据';
                break;
        }
        result.dataTypeName = dataTypeName;
        _log('DEBUG', `[遥测数据解析] 数据类型(dataType): ${result.dataType} (${result.dataTypeName})`);
        
        _log('DEBUG', `[遥测数据解析] 参数个数(parNum): ${result.parNum}`);
        
        // 数据状态名称
        result.stateName = result.state === 0 ? '正常' : '断帧（sample采样率周期）';
        _log('DEBUG', `[遥测数据解析] 数据状态(state): ${result.state} (${result.stateName})`);
        
        // 工作模式名称
        result.workModeName = result.workMode === 0 ? '实时' : '回放';
        _log('DEBUG', `[遥测数据解析] 工作模式(workMode): ${result.workMode} (${result.workModeName})`);
        
        _log('DEBUG', `[遥测数据解析] 备用1(reserved1): ${result.reserved1}`);
        
        if (result.sample < 1 || result.sample > 1024) {
            _log('WARN', `[遥测数据解析] 采样率值超出范围: ${result.sample}`);
        }
        _log('DEBUG', `[遥测数据解析] 采样率(sample): ${result.sample}`);
        
        _log('DEBUG', `[遥测数据解析] 备用2(reserved2): ${result.reserved2}`);
        _log('DEBUG', `[遥测数据解析] 备用3(reserved3): ${result.reserved3}`);
        
        // 系统时间日志和验证 - 增强验证逻辑
        _log('DEBUG', `[遥测数据解析] 系统时间: ${result.sysTime.hour}:${result.sysTime.minute}:${result.sysTime.second}.${result.sysTime.ms}`);
        if (result.sysTime.hour < 0 || result.sysTime.hour > 23) {
            _log('WARN', `[遥测数据解析] 系统时间时值超出范围: ${result.sysTime.hour}`);
        }
        if (result.sysTime.minute < 0 || result.sysTime.minute > 59) {
            _log('WARN', `[遥测数据解析] 系统时间分值超出范围: ${result.sysTime.minute}`);
        }
        if (result.sysTime.second < 0 || result.sysTime.second > 59) {
            _log('WARN', `[遥测数据解析] 系统时间秒值超出范围: ${result.sysTime.second}`);
        }
        if (result.sysTime.ms < 0 || result.sysTime.ms > 999) {
            _log('WARN', `[遥测数据解析] 系统时间毫秒值超出范围: ${result.sysTime.ms}`);
        }
        
        // 数据时间日志和验证
        _log('DEBUG', `[遥测数据解析] 数据时间: ${result.dataTime.hour}:${result.dataTime.minute}:${result.dataTime.second}.${result.dataTime.ms}`);
        if (result.dataTime.hour < 0 || result.dataTime.hour > 23) {
            _log('WARN', `[遥测数据解析] 数据时间时值超出范围: ${result.dataTime.hour}`);
        }
        if (result.dataTime.minute < 0 || result.dataTime.minute > 59) {
            _log('WARN', `[遥测数据解析] 数据时间分值超出范围: ${result.dataTime.minute}`);
        }
        if (result.dataTime.second < 0 || result.dataTime.second > 59) {
            _log('WARN', `[遥测数据解析] 数据时间秒值超出范围: ${result.dataTime.second}`);
        }
        if (result.dataTime.ms < 0 || result.dataTime.ms > 999) {
            _log('WARN', `[遥测数据解析] 数据时间毫秒值超出范围: ${result.dataTime.ms}`);
        }

        // 读取参数值（假设 RY-PAR-RESULT 为 4字节 float）
        const remainingBytes = view.byteLength - offset;
        if (result.parNum > 0 && remainingBytes >= result.parNum * 4) {
            for (let i = 0; i < result.parNum && offset + 4 <= view.byteLength; i++) {
                const value = view.getFloat32(offset, true);
                result.params.push(value);
                _log('DEBUG', `[遥测数据解析] 参数${i + 1}: ${value} (小端序float)`);
                offset += 4;
            }
        } else if (result.parNum > 0) {
            _log('WARN', `[遥测数据解析] 剩余字节数(${remainingBytes})不足解析${result.parNum}个参数`);
        }

        // 验证总数据长度
        if (offset !== view.byteLength) {
            _log('WARN', `[遥测数据解析] 解析的数据长度${offset}与总长度${view.byteLength}不匹配`);
        }

        return result;
    } catch (error) {
        _log('ERROR', `[遥测数据解析] 解析错误: ${error.message}`);
        return null;
    }
}

// 独立的handletelemetryData函数实现 - 使用DataView改进版
function handletelemetryData() {
    try {
        console.log(`\n=== 测试数据信息 ===`);
        
        // 直接定义十六进制字符串作为测试数据
        // 这个字符串表示80字节的遥测数据，包含5个参数
        // 字段顺序：包长(4字节)+报序号(4字节)+任务ID(4字节)+型号ID(4字节)+编号(2字节)+源类型(1字节)+数据类型(1字节)+参数个数(4字节)+数据状态(1字节)+工作模式(1字节)+备用1(1字节)+采样率(2字节)+备用2(1字节)+备用3(1字节)+系统时间(4字节*4)+数据时间(4字节*4)+参数数据(4字节*5)
        const hexString = '80 00 00 00 00 00 00 00 0A 59 07 00 01 00 01 00 93 00 00 00 45 02 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 10 00 00 00 04 00 00 00 1B 00 00 00 0D 00 00 00 02 00 00 00 1A 00 00 00 06 00 00 00 F7 00 00 00 00 00 00 00 03 00 00 00 03 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00';
        
        // 验证十六进制字符串
        const cleanedHexString = hexString.replace(/\s|0x/gi, '');
        console.log(`测试数据十六进制字符串长度: ${cleanedHexString.length} 字符`);
        console.log(`预计数据长度: ${cleanedHexString.length / 2} 字节`);
        
        // 使用大端序和小端序分别解析数据
        console.log('\n=== 大端序解析结果 ===');
        const bigEndianResult = parseEngineeringDataWithEndianness(hexString, false); // false表示大端序
        
        console.log('\n=== 小端序解析结果 ===');
        const littleEndianResult = parseEngineeringDataWithEndianness(hexString, true); // true表示小端序
        
        // 输出大端序和小端序的对比
        console.log('\n=== 大端序和小端序解析结果对比 ===');
        console.log('| 字段名 | 大端序值 | 小端序值 | 差异 |');
        console.log('|--------|----------|----------|------|');
        
        // 比较并输出主要字段的差异
        if (bigEndianResult && littleEndianResult) {
            // 比较基本信息
            const fieldsToCompare = [
                {name: '包长(packLen)', bigEndian: bigEndianResult.packLen, littleEndian: littleEndianResult.packLen},
                {name: '报序号(packNo)', bigEndian: bigEndianResult.packNo, littleEndian: littleEndianResult.packNo},
                {name: '任务ID(taskID)', bigEndian: bigEndianResult.taskID, littleEndian: littleEndianResult.taskID},
                {name: '型号ID(modlID)', bigEndian: bigEndianResult.modlID, littleEndian: littleEndianResult.modlID},
                {name: '编号(no)', bigEndian: bigEndianResult.no, littleEndian: littleEndianResult.no},
                {name: '参数个数(parNum)', bigEndian: bigEndianResult.parNum, littleEndian: littleEndianResult.parNum},
                {name: '采样率(sample)', bigEndian: bigEndianResult.sample, littleEndian: littleEndianResult.sample}
            ];
            
            fieldsToCompare.forEach(field => {
                const isDifferent = field.bigEndian !== field.littleEndian;
                console.log(`| ${field.name} | ${field.bigEndian} | ${field.littleEndian} | ${isDifferent ? '✓' : '✗'} |`);
            });
            
            // 比较参数值
            console.log('\n参数值对比:');
            const paramCount = Math.max(bigEndianResult.params.length, littleEndianResult.params.length);
            for (let i = 0; i < paramCount; i++) {
                const bigEndianParam = i < bigEndianResult.params.length ? bigEndianResult.params[i] : 'N/A';
                const littleEndianParam = i < littleEndianResult.params.length ? littleEndianResult.params[i] : 'N/A';
                const isDifferent = bigEndianParam !== littleEndianParam && bigEndianParam !== 'N/A' && littleEndianParam !== 'N/A';
                console.log(`参数${i+1}: 大端序=${bigEndianParam}, 小端序=${littleEndianParam}${isDifferent ? ' (差异)' : ''}`);
            }
        }
        
        // 返回小端序的结果作为默认结果
        return littleEndianResult;
        
    } catch (error) {
        _log('ERROR', `[遥测数据解析] 解析遥测数据时出错: ${error.message}`);
        return null;
    }
}

/**
 * 根据指定的字节序解析工程数据
 * @param {string} hexString - 十六进制字符串
 * @param {boolean} isLittleEndian - 是否小端序，true为小端序，false为大端序
 * @returns {object} 解析后的结果对象
 */
function parseEngineeringDataWithEndianness(hexString, isLittleEndian) {
    try {
        // 去掉空格 
        hexString = hexString.replace(/\s+/g, '');

        // 验证输入是否为有效的十六进制字符串
        if (!/^[0-9A-Fa-f]+$/.test(hexString)) {
            _log('ERROR', `[遥测数据解析(${isLittleEndian ? '小端序' : '大端序'})] 无效的十六进制字符串`);
            return null;
        }

        // 十六进制转字节数组 
        const bytes = new Uint8Array(hexString.length / 2); 
        for (let i = 0; i < bytes.length; i++) {
            bytes[i] = parseInt(hexString.substr(i * 2, 2), 16); 
        }

        const view = new DataView(bytes.buffer); 
        let offset = 0; 

        // 按工程数据格式读取
        const result = {
            // 工程数据格式头部字段
            packLen: view.getUint32(offset, isLittleEndian), // 包长：4字节，无符号长整数
            packNo: view.getUint32(offset += 4, isLittleEndian), // 报序号：4字节，无符号长整数
            taskID: view.getUint32(offset += 4, isLittleEndian), // 任务ID：4字节，无符号长整数
            modlID: view.getUint32(offset += 4, isLittleEndian), // 型号ID：4字节，无符号长整数
            no: view.getUint16(offset += 4, isLittleEndian), // 编号：2字节，无符号短整数
            danType: view.getUint8(offset += 2), // 源类型：1字节，单字节
            dataType: view.getUint8(offset += 1), // 数据类型：1字节，单字节
            parNum: view.getUint32(offset += 1, isLittleEndian), // 参数个数：4字节，无符号长整数
            state: view.getUint8(offset += 4), // 数据状态：1字节，单字节
            workMode: view.getUint8(offset += 1), // 工作模式：1字节，单字节
            reserved1: view.getUint8(offset += 1), // 备用1：1字节，单字节
            sample: view.getUint16(offset += 1, isLittleEndian), // 采样率：2字节，无符号短整数
            reserved2: view.getUint8(offset += 2), // 备用2：1字节，单字节
            reserved3: view.getUint8(offset += 1), // 备用3：1字节，单字节

            // 系统时间字段
            sysTime: {
                hour: view.getUint32(offset += 1, isLittleEndian), // 系统时间-时：4字节，无符号长整数
                minute: view.getUint32(offset += 4, isLittleEndian), // 系统时间-分：4字节，无符号长整数
                second: view.getUint32(offset += 4, isLittleEndian), // 系统时间-秒：4字节，无符号长整数
                ms: view.getUint32(offset += 4, isLittleEndian), // 系统时间-毫秒：4字节，无符号长整数
            },

            // 数据时间字段
            dataTime: {
                hour: view.getUint32(offset += 4, isLittleEndian), // 数据时间-时：4字节，无符号长整数
                minute: view.getUint32(offset += 4, isLittleEndian), // 数据时间-分：4字节，无符号长整数
                second: view.getUint32(offset += 4, isLittleEndian), // 数据时间-秒：4字节，无符号长整数
                ms: view.getUint32(offset += 4, isLittleEndian), // 数据时间-毫秒：4字节，无符号长整数
            },

            params: []
        };

        // 记录字节序信息
        result.endianness = isLittleEndian ? 'little-endian' : 'big-endian';
        
        // 输出字节序相关日志
        _log('INFO', `[遥测数据解析(${isLittleEndian ? '小端序' : '大端序'})] 包长: ${result.packLen}, 任务ID: ${result.taskID}`);

        // 读取参数值（假设 RY-PAR-RESULT 为 4字节 float）
        const remainingBytes = view.byteLength - offset;
        if (result.parNum > 0 && remainingBytes >= result.parNum * 4) {
            for (let i = 0; i < result.parNum && offset + 4 <= view.byteLength; i++) {
                const value = view.getFloat32(offset, isLittleEndian);
                result.params.push(value);
                _log('DEBUG', `[遥测数据解析(${isLittleEndian ? '小端序' : '大端序'})] 参数${i + 1}: ${value}`);
                offset += 4;
            }
        } 
        
        _log('INFO', `[遥测数据解析(${isLittleEndian ? '小端序' : '大端序'})] 成功解析，参数个数: ${result.params.length}`);
        
        return result;
    } catch (error) {
        _log('ERROR', `[遥测数据解析(${isLittleEndian ? '小端序' : '大端序'})] 解析错误: ${error.message}`);
        return null;
    }
}

console.log('=== 开始测试handletelemetryData方法 ===\n');

try {
    // 直接调用独立的handletelemetryData函数
    const result = handletelemetryData();
    
    console.log('\n=== 解析结果摘要 ===');
    
    // 打印主要解析结果
    if (result) {
        console.log('1. 基本信息:');
        console.log(`   - 包长(packLen): ${result.packLen}`);
        console.log(`   - 报序号(packNo): ${result.packNo}`);
        console.log(`   - 任务ID(taskID): ${result.taskID}`);
        console.log(`   - 型号ID(modlID): ${result.modlID}`);
        
        console.log('\n2. 数据类型信息:');
        console.log(`   - 数据类型(dataType): ${result.dataType} (${result.dataTypeName})`);
        console.log(`   - 源类型(danType): ${result.danType} (${result.sourceTypeName})`);
        console.log(`   - 工作模式(workMode): ${result.workMode} (${result.workModeName})`);
        
        console.log('\n3. 时间信息:');
        console.log(`   - 系统时间: ${result.sysTime.hour}:${result.sysTime.minute}:${result.sysTime.second}.${result.sysTime.ms}`);
        console.log(`   - 数据时间: ${result.dataTime.hour}:${result.dataTime.minute}:${result.dataTime.second}.${result.dataTime.ms}`);
        
        console.log('\n4. 参数信息:');
        console.log(`   - 参数个数: ${result.parNum}`);
        if (result.params && result.params.length > 0) {
            console.log('   - 参数值列表:');
            result.params.forEach((param, index) => {
                console.log(`     参数${index + 1}: ${param}`);
            });
        }
        
        // 打印完整的解析结果，便于调试
        console.log('\n=== 完整解析结果 ===');
        console.log(JSON.stringify(result, null, 2));
    } else {
        console.log('解析失败，未返回结果');
    }
} catch (error) {
    console.error('测试出错:', error.message);
    console.error(error.stack);
}

console.log('\n=== 测试完成 ===');